单例模式 Singleton Pattern

  1. 私有化 构造器
  2. 私有化 静态变量
  3. 公有化 对象获取函数返回一个实例

定义单例模式

确保一个类只有一个实例,并提供一个全局访问点。

懒汉单例模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* 最经典的懒汉单件模式
*/
public class Singleton {

private volatile static Singleton instance;//定义静态实例变量

/**
* 定义私有构造方法,防止从外部new实例
*/
private Singleton(){
//初始化操作
}

/**
* 提供全局访问点
* 双重检查加锁
* @return 该类的实例
*/
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class){
if(instance == null)
instance = new Singleton();
}
}
return instance;
}

/**
* 其它有用的属性和行为
* 毕竟应用了单件模式的类仍然具有原本的功能
*/
}
1
2
3
4
5
6
7
8
9
volatile :原子性。它作用是解决是因为
//1:分配对象的内存空间
//2:初始化对象
//3:设置instance指向刚分配的内存地址

2 初始化对象 与 3 设置 instance 指向分配的内存地址可
能会发生顺序交换,导致问题

volatile关键字会告诉编译器,不要对该对象进行编译优化

饿汗单例模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 饿汉单件模式
*/
public class Singleton {

private static Singleton instance = new Singleton();//定义静态实例变量

/**
* 定义私有构造方法,防止从外部new实例
*/
private Singleton(){
//初始化操作
}

/**
* 提供全局访问点
* @return 该类的实例
*/
public static Singleton getInstance(){
return instance;
}

/**
* 其它有用的属性和行为
* 毕竟应用了单件模式的类仍然具有原本的功能
*/
}

多个class loader环境下的单件模式

如果存在多个类加载器,多个类加载器可能同时加载我们的单件类,从而产生多个实例
对于这种情况,我们可以显式指定使用哪一个class loader来加载单件类,这样就有效避免了上述问题